package com.heima.search.Service.impl;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.heima.article.feign.ApArticleFeign;
import com.heima.common.dtos.ResponseResult;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.search.dtos.ArticleDocumentVo;
import com.heima.model.search.dtos.UserSearchDto;
import com.heima.model.search.pojos.ArticleDocument;
import com.heima.model.user.pojos.ApUser;
import com.heima.search.Service.ApUserSearchService;
import com.heima.search.Service.ArticleSearchService;
import com.heima.search.repository.ArticleDocumentRepository;
import com.heima.utils.common.BeanHelper;
import com.heima.utils.common.ThreadLocalUtils;
import org.apache.poi.ss.formula.functions.Na;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class ArticleSearchServiceImpl implements ArticleSearchService {
    @Autowired
    private ElasticsearchRestTemplate restTemplate;
    @Autowired
    private ApArticleFeign apArticleFeign;
    @Autowired
    private ArticleDocumentRepository articleDocumentRepository;
    @Autowired
    private ApUserSearchService apUserSearchService;
    @Override
    public ResponseResult<List<ArticleDocumentVo>> search(UserSearchDto dto) {
        try {
            //构建查询对象构造器
            NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();

            //往构造器添加各种条件(***)
            //Query部分
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            boolQueryBuilder.must(QueryBuilders.matchQuery("title",dto.getSearchWords()));
            boolQueryBuilder.must(QueryBuilders.rangeQuery("publishTime").lt(dto.getMinBehotTime().getTime()));
            queryBuilder.withQuery(boolQueryBuilder);

            //Page部分
            /**
             * page:页码，从0开始计算的
             * size: 每页大小
             */
            queryBuilder.withPageable(PageRequest.of(0,dto.getPageSize()));

            //Sort部分
            queryBuilder.withSort(SortBuilders.fieldSort("publishTime").order(SortOrder.DESC));

            //Highlight部分
            HighlightBuilder.Field field = new HighlightBuilder.Field("title");
            field.preTags("<font style='color: red; font-size: inherit;'>");
            field.postTags("</font>");
            queryBuilder.withHighlightFields(field);

            //从构造器获取查询对象（查询对象：封装了各种查询条件的对象）
            NativeSearchQuery searchQuery = queryBuilder.build();

            //使用查询对象执行全文检索，获取结果
            //SearchHits: 查询结果的封装对象
            SearchHits<ArticleDocument> searchHits = restTemplate.search(searchQuery, ArticleDocument.class);

            //处理结果，并返回
            List<ArticleDocumentVo> list = new ArrayList<>();

            //遍历searchHits
            for(SearchHit<ArticleDocument> hit:searchHits){
                ArticleDocument articleDocument = hit.getContent();
                ArticleDocumentVo articleDocumentVo = BeanHelper.copyProperties(articleDocument, ArticleDocumentVo.class);

                //处理高亮字段
                //取出高亮显示结果
                List<String> title = hit.getHighlightFields().get("title");
                if(CollectionUtils.isNotEmpty(title)){
                    //设置到原对象中
                    articleDocumentVo.setH_title(title.get(0));
                }

                list.add(articleDocumentVo);
            }

            //判断只有登录用户才需要记录用户搜索历史
            ApUser apUser = (ApUser)ThreadLocalUtils.get();
            if(apUser!=null) {
                apUserSearchService.insert(apUser.getId(),dto.getSearchWords());
            }

            return ResponseResult.okResult(list);
        } finally {
            ThreadLocalUtils.remove();
        }
    }

    @Override
    public void saveToES(Long articleId) {
        //根据id查询App文章
        ResponseResult<ApArticle> responseResult = apArticleFeign.findArticleById(articleId);
        if(responseResult.getCode().equals(200)){
            ApArticle article = responseResult.getData();
            //保存到ES
            ArticleDocument articleDocument = BeanHelper.copyProperties(article,ArticleDocument.class);
            articleDocumentRepository.save(articleDocument);
        }

    }

    @Override
    public void removeFromES(Long articleId) {
        articleDocumentRepository.deleteById(articleId);
    }
}
